package com.info33.platform.business.pay.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import cn.hutool.json.JSONUtil;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.WxPayKit;
import com.info33.platform.business.pay.dao.TextDao;
import com.info33.platform.business.pay.dto.TextDTO;
import com.info33.platform.business.pay.entity.Text;
import com.info33.platform.business.pay.service.TextService;
import com.info33.platform.common.mvc.vo.Result;
import com.info33.platform.common.pay.AlipayNotifyParam;
import com.info33.platform.common.pay.AlipayUtil;
import com.info33.platform.common.pay.WxPayV3Api;
import com.info33.platform.common.pay.WxPayV3Bean;
import com.info33.platform.config.pay.PayAsyncNotify;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class TextServiceImpl extends ServiceImpl<TextDao, Text> implements TextService {

    @Autowired
    TextDao textDao;
    @Autowired
    WxPayV3Bean wxPayV3Bean;
    @Autowired
    PayAsyncNotify payAsyncNotify;


    @Override
    public Result<Object> appPay(HttpServletRequest request, TextDTO dto) throws Exception {
        //进行吊起支付前的订单校验
        //然后根据选择调取哪个支付
        if (ObjectUtils.isEmpty(dto.getPayWay())) {
            return Result.error("支付方式异常!");
        } else {
            if (dto.getPayWay() == 1) {
                return WxPayV3Api.appApiPay("订单描述", dto.getOrderNumber(), dto.getRealPrice(), payAsyncNotify.getAdoptWx(), 30, null);
            } else {
                return AlipayUtil.pay(payAsyncNotify.getAdoptZfb(), "认养订单", dto.getOrderNumber(), String.valueOf(dto.getRealPrice()));
            }
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void breakInfo(HttpServletRequest request, HttpServletResponse response) throws Exception {
        AlipayNotifyParam paramEntity = null;

        try {
            paramEntity = AlipayUtil.formatRequest(request, response);
            System.out.println("判断OutBizNo:" + ObjectUtils.isEmpty(paramEntity.getOutBizNo()));
            //OutBizNo,RefundFee,GmtRefund三个字段,如果存在表示当前回调为退款回调,否则为支付成功回调
            System.out.println("支付宝请求返回："  + paramEntity);

            //---start---在回调内对数据进行处理
            //|||||||||||
            //---end---在回调内对数据进行处理

            //成功必须返回success,否则支付宝会在25小时之内八次调用该回调,导致成功以后的步骤都有可能因为该回调发生不可预料的后果(比如返回待发货状态)
            response.getWriter().write("success");

        } catch (Exception e) {
            e.printStackTrace();
            // 出现异常，支付取消
            if (!ObjectUtils.isEmpty(paramEntity)) {
                AlipayUtil.cancel(paramEntity.getTradeNo());
            }
            //失败返回failure,否则支付宝会在25小时之内八次调用该回调
            response.getWriter().write("failure");
            e.printStackTrace();
        }

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void wxPayNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("收到支付成功的通知");
        Map<String, String> map = new HashMap<>(12);

        try {
            String timestamp = request.getHeader("Wechatpay-Timestamp");
            String nonce = request.getHeader("Wechatpay-Nonce");
            String serialNo = request.getHeader("Wechatpay-Serial");
            String signature = request.getHeader("Wechatpay-Signature");

            log.info("timestamp:{} nonce:{} serialNo:{} signature:{}", timestamp, nonce, serialNo, signature);
            String result = HttpKit.readData(request);
            log.info("支付通知密文 {}", result);

            // 需要通过证书序列号查找对应的证书，verifyNotify 中有验证证书的序列号
            String plainText = WxPayKit.verifyNotify(serialNo, result, signature, nonce, timestamp,
                    wxPayV3Bean.getApiKey3(), wxPayV3Bean.getPlatformCertPath());
            log.info("支付通知明文 {}", plainText);

            if (StrUtil.isNotEmpty(plainText)) {
                response.setStatus(200);
                map.put("code", "SUCCESS");
                map.put("message", "SUCCESS");

                //---start---在回调内对数据进行处理
                //|||||||||||
                //---end---在回调内对数据进行处理

            }else {
                response.setStatus(500);
                map.put("code", "ERROR");
                map.put("message", "签名错误");
            }
            response.setHeader("Content-type", ContentType.JSON.toString());
            response.getOutputStream().write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
            response.flushBuffer();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Result<?> payZfbRefund(TextDTO dto) throws Exception {
        AlipayTradeRefundResponse refund = AlipayUtil.refund(dto.getOrderNumber(), dto.getRefundPrice().toString());
        if (refund.getCode().equals("10000")) {
            if (refundGeneral(dto, refund.getTradeNo(), refund.getOutTradeNo())) {
                return Result.ok("退款成功!");
            }
        }
        // 全额退款返回TRADE_CLOSED(交易关闭)走正常流程,但如果客户进入支付宝官网手动操作退款且分多次退款,
        // 部分退款返回TRADE_FINISHED(交易完成),将不会走正常流程,除非钱全部退完为止.
        // 部分退款会触发回调通知
        if (refund.getCode().equals("40004")) {
            AlipayTradeQueryResponse query = AlipayUtil.query(dto.getOrderNumber());
            //卖家可能会因为各种原因,退款失败,只能进入支付宝官方进行手动退款
            //query内的trade_status状态为TRADE_CLOSED时表示:未付款交易超时关闭，或支付完成后全额退款
            //但当前订单号状态如果为RETURN_SENT(10:退货已发送),则TRADE_CLOSED表示付完成后全额退款
            if (dto.getAdoptStatus().equals(10) && query.getTradeStatus().equals("TRADE_CLOSED")) {
                if (refundGeneral(dto, refund.getTradeNo(), refund.getOutTradeNo())) {
                    return Result.ok("退款成功!");
                }
            }
            return Result.error("支付宝通知:" + refund.getSubMsg());
        }
        throw new Exception("退款失败！" + refund.getSubMsg());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Result<?> payWxRefund(TextDTO dto) throws Exception {
        //微信退款有单独的回调
        String s = WxPayV3Api.wxRefund(dto.getPayNo(), dto.getOrderNumber(), payAsyncNotify.getAdoptWxRefund(), dto.getRealPrice(), dto.getRefundPrice());
        Map<String, String> stringStringMap = WxPayKit.xmlToMap(s);
        log.info("stringStringMap:{}", stringStringMap);
        if (!StringUtils.isEmpty(s)) {
            if (stringStringMap.get("return_code").equals("SUCCESS")) {
                if (refundGeneral(dto, stringStringMap.get("refund_id"), stringStringMap.get("out_refund_no")))
                    return Result.ok("退款成功!");
            } else {
                return Result.error("微信通知:" + stringStringMap.get("err_code_des"));
            }
        }
        throw new Exception("退款失败！"+ stringStringMap.get("err_code_des"));
    }

    /**
     * 支付退款,订单状态修改(通用)
     *
     * @param dto        参数
     * @param tradeNo    第三方的退款单号(微信、支付宝)
     * @param outTradeNo 商户退款单号
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    boolean refundGeneral(TextDTO dto, String tradeNo, String outTradeNo) throws Exception {
        //---start---在回调内对数据进行退货退款处理
        //|||||||||||
        //---end---在回调内对数据进行退货退款处理
//        AdoptFarmProductOrder adoptFarmProductOrder = adoptFarmProductOrderDao.selectById(dto.getId());
//        adoptFarmProductOrder.setRefundId(tradeNo);
//        adoptFarmProductOrder.setOutRefundNo(outTradeNo);
//        adoptFarmProductOrder.setAdoptStatus(AdoptConstant.AdoptStatus.REFUND);
//        int i = adoptFarmProductOrderDao.updateById(adoptFarmProductOrder);
//        if (i == 1) {
//            //使库存增加购买的数量
//            AdoptFarmProduct adoptFarmProduct = adoptFarmProductDao.selectById(adoptFarmProductOrder.getFarmProductId());
//
//            adoptFarmProduct.setAdoptedNum(adoptFarmProduct.getAdoptedNum() - adoptFarmProductOrder.getOrderQuantity());
//            adoptFarmProduct.setRemainNum(adoptFarmProduct.getRemainNum() + adoptFarmProductOrder.getOrderQuantity());
//            adoptFarmProduct.setAdoptPeopleNum(adoptFarmProduct.getAdoptPeopleNum() - 1);
//            if (adoptFarmProductDao.updateById(adoptFarmProduct) < 0) {
//                throw new UpdateStockException("修改库存失败");
//            }
//            String message = "您的" + adoptFarmProduct.getName() + "认养订单已成功退款至";
//            if (dto.getPayWay().equals(1)) {
//                message += "微信!";
//            } else if (dto.getPayWay().equals(2)) {
//                message += "支付宝!";
//            } else {
//                message += "账户余额!";
//            }
//            if (PushMessageUtil.pushMessage(InfoType.ADOPT_ORDER, message, adoptFarmProductOrder.getCreateBy(), null)) {
//                return true;
//            }
//        }
        throw new Exception("系统错误！");
    }

}
